package fss

import (
	"fmt"
	"net/url"
	"reflect"
)

type (
	StreamModel struct {
		Vhost         string `json:"vhost"`           // 添加的流的虚拟主机，例如__defaultVhost__
		App           string `json:"app"`             // 添加的流的应用名，例如 live
		Stream        string `json:"stream"`          // 添加的流的 id 名，例如 test
		URL           string `json:"url"`             // 拉流地址，例如 rtmp://live.hkstv.hk.lxdns.com/live/hks2
		RetryCount    int    `json:"retry_count"`     // 拉流重试次数，默认为-1 无限重试
		RTPType       int    `json:"rtp_type"`        // rtsp 拉流时，拉流方式，0：tcp，1：udp，2：组播
		TimeoutSec    int    `json:"timeout_sec"`     // 拉流超时时间，单位秒，float 类型
		EnableHLS     bool   `json:"enable_hls"`      // 是否转换成 hls-mpegts 协议
		EnableHLSFMP4 bool   `json:"enable_hls_fmp4"` // 是否转换成 hls-fmp4 协议
		EnableMP4     bool   `json:"enable_mp4"`      // 是否允许 mp4 录制
		EnableRTSP    bool   `json:"enable_rtsp"`     // 是否转 rtsp 协议
		EnableRTMP    bool   `json:"enable_rtmp"`     // 是否转 rtmp/flv 协议
		EnableTS      bool   `json:"enable_ts"`       // 是否转 http-ts/ws-ts 协议
		EnableFMP4    bool   `json:"enable_fmp4"`     // 是否转 http-fmp4/ws-fmp4 协议
		HLSDemand     bool   `json:"hls_demand"`      // 该协议是否有人观看才生成
		RTSPDemand    bool   `json:"rtsp_demand"`     // 该协议是否有人观看才生成
		RTMPDemand    bool   `json:"rtmp_demand"`     // 该协议是否有人观看才生成
		TSDemand      bool   `json:"ts_demand"`       // 该协议是否有人观看才生成
		FMP4Demand    bool   `json:"fmp_4_demand"`    // 该协议是否有人观看才生成
		EnableAudio   bool   `json:"enable_audio"`    // 转协议时是否开启音频
		AddMuteAudio  bool   `json:"add_mute_audio"`  // 转协议时，无音频是否添加静音 aac 音频
		MP4SavePath   string `json:"mp4_save_path"`   // mp4 录制文件保存根目录，置空使用默认
		MP4MaxSecond  int    `json:"mp4_max_second"`  // mp4 录制切片大小，单位秒
		MP4AsPlayer   bool   `json:"mp4_as_player"`   // mp4 录制是否当作观看者参与播放人数计数
		HLSSavePath   string `json:"hls_save_path"`   // hls 文件保存保存根目录，置空使用默认
		ModifyStamp   int    `json:"modify_stamp"`    // 该流是否开启时间戳覆盖(0:绝对时间戳/1:系统时间戳/2:相对时间戳)
		AutoClose     bool   `json:"auto_close"`      // 无人观看是否自动关闭流(不触发无人观看 hook)
	}

	// Track 音视频轨道
	Track struct {
		Channels      int     `json:"channels"`                  // 音频通道数
		CodecId       int     `json:"codec_id"`                  //  H264 = 0, H265 = 1, AAC = 2, G711A = 3, G711U = 4
		CodecIdName   string  `json:"codec_id_name"`             // 编码类型名称
		CodecType     int     `json:"codec_type"`                // Video = 0, Audio = 1
		Ready         bool    `json:"ready"`                     // 轨道是否准备就绪
		Frames        int     `json:"frames"`                    // 累计接收帧数
		SampleBit     int     `json:"sample_bit,omitempty"`      // 音频采样位数
		SampleRate    int     `json:"sample_rate,omitempty"`     // 音频采样率
		FPS           float32 `json:"fps,omitempty"`             // 视频fps
		GopIntervalMs int     `json:"gop_interval_ms,omitempty"` // gop间隔时间，单位毫秒
		GopSize       int     `json:"gop_size,omitempty"`        // gop大小，单位帧数
		KeyFrames     int     `json:"key_frames,omitempty"`      // 累计接收关键帧数
		Height        int     `json:"height,omitempty"`          // 视频高
		Width         int     `json:"width,omitempty"`           // 视频宽
	}

	// OriginSock 客户端和服务器网络信息，可能为null类型
	OriginSock struct {
		Identifier string `json:"identifier"`
		LocalIp    string `json:"local_ip"`
		LocalPort  int    `json:"local_port"`
		PeerIp     string `json:"peer_ip"`
		PeerPort   int    `json:"peer_port"`
	}

	MediaInfo struct {
		App              string      `json:"app"`              // 应用名
		VHost            string      `json:"vhost"`            // 虚拟主机名
		ReaderCount      int         `json:"readerCount"`      // 本协议观看人数
		TotalReaderCount int         `json:"totalReaderCount"` // 观看总人数，包括hls/rtsp/rtmp/http-flv/ws-flv
		Schema           string      `json:"schema"`           // 协议
		Stream           string      `json:"stream"`           // 流id
		OriginSock       *OriginSock `json:"originSock"`       // 客户端和服务器网络信息，可能为null类型
		Tracks           []Track     `json:"tracks"`           // 音视频轨道
		BytesSpeed       int         `json:"bytesSpeed"`       // 数据产生速度，单位byte/s
		AliveSecond      int         `json:"aliveSecond"`      // 存活时间，单位秒
		CreateStamp      int         `json:"createStamp"`      // GMT unix系统时间戳，单位秒
		OriginUrl        string      `json:"originUrl"`        // 产生源的url
		OriginTypeStr    string      `json:"originTypeStr"`    //
		OriginType       int         `json:"originType"`       // 产生源类型，包括 unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7
	}
)

// DefaultStreamModel 生成流配置
func DefaultStreamModel(app, stream, url string) *StreamModel {
	return NewStreamModel("__defaultVhost__", app, stream, url)
}

// NewStreamModel 生成流配置
func NewStreamModel(vhost, app, stream, url string) *StreamModel {
	return &StreamModel{
		Vhost:         vhost,
		App:           app,
		Stream:        stream,
		URL:           url,
		RetryCount:    -1,
		RTPType:       0,
		TimeoutSec:    5,
		EnableHLS:     false,
		EnableHLSFMP4: false,
		EnableMP4:     false,
		EnableRTSP:    true,
		EnableRTMP:    true,
		EnableTS:      true,
		EnableFMP4:    true,
		HLSDemand:     false,
		RTSPDemand:    false,
		RTMPDemand:    false,
		TSDemand:      false,
		FMP4Demand:    false,
		EnableAudio:   true,
		AddMuteAudio:  false,
		//MP4SavePath:   "",
		MP4MaxSecond: 10,
		MP4AsPlayer:  false,
		//HLSSavePath:   "",
		//ModifyStamp:   0,
		AutoClose: false,
	}
}

func (m *StreamModel) ToQuery() string {
	v := reflect.ValueOf(m)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}
	values := url.Values{}
	for i := 0; i < v.NumField(); i++ {
		f := v.Field(i)
		if !f.IsZero() {
			values.Add(v.Type().Field(i).Tag.Get("json"), fmt.Sprintf("%v", f))
		}
	}
	return values.Encode()
}
